package com.hzw.saas.service.tripartite;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzw.saas.api.property.IPropertyService;
import com.hzw.saas.api.property.bo.PropertyBO;
import com.hzw.saas.api.user.IUserTripartiteService;
import com.hzw.saas.api.user.bo.UserWeTripartiteBO;
import com.hzw.saas.api.user.bo.WechatRequestBO;
import com.hzw.saas.common.config.auth.param.PlatformParam;
import com.hzw.saas.common.config.auth.param.WeChatTokenParam;
import com.hzw.saas.common.config.auth.param.WeChatUserInfoParam;
import com.hzw.saas.common.util.MapperUtil;
import com.hzw.saas.common.util.SnowFlakeUtil;
import com.hzw.saas.service.property.enums.ModuleEnum;
import com.hzw.saas.service.tripartite.mapper.UserWeTripartiteMapper;
import com.hzw.saas.service.tripartite.model.UserWeTripartite;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("userWeTripartiteService")
public class UserTripartiteServiceImpl extends ServiceImpl<UserWeTripartiteMapper, UserWeTripartite> implements IUserTripartiteService, IService<UserWeTripartite> {

    @Resource(name = "sysParamService")
    private IPropertyService propertyService;

    @Override
    public WeChatTokenParam getWechatByCode(String code, String type) {
        //根据code拿到用户的的回调信息
        List<WechatRequestBO> wechatRequest = getWechatRequest(type);
        if (CollectionUtil.isEmpty(wechatRequest) || wechatRequest.size() > 1) {
            return new WeChatTokenParam();
        }
        WechatRequestBO wechatRequestBO = wechatRequest.get(0);
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + wechatRequestBO.getAppId() +
            "&secret=" + wechatRequestBO.getAppSecret() + "&code="+code +"&grant_type=authorization_code";
        String s = HttpUtil.get(url);
        log.debug("微信返回消息为："+s);
        JSONObject jsonObject = JSONObject.fromObject(s);
        WeChatTokenParam weChatTokenParam = (WeChatTokenParam) JSONObject.toBean(jsonObject, WeChatTokenParam.class);
        return weChatTokenParam;
    }

    @Override
    public WeChatUserInfoParam getWeChatUserInfoParam(String accessToken, String openId,String unionId,String type){
        if (StrUtil.isBlank(accessToken)||StrUtil.isBlank(openId)||StrUtil.isBlank(unionId)){
            return null;
        }
        String uri = "https://api.weixin.qq.com/sns/userinfo?access_token="+accessToken+"&openid="+openId;
        String s1 = HttpUtil.get(uri);
        JSONObject fromObject = JSONObject.fromObject(s1);
        WeChatUserInfoParam weChatUserInfoParam = (WeChatUserInfoParam) JSONObject.toBean(fromObject, WeChatUserInfoParam.class);
        if (weChatUserInfoParam != null && StrUtil.isNotBlank(weChatUserInfoParam.getNickname())){
            List<UserWeTripartiteBO> byUnionIdAndOpenId = getByUnionIdAndOpenId(unionId, openId, ModuleEnum.getDataByCode(type));
            if (CollectionUtil.isNotEmpty(byUnionIdAndOpenId)){
                UserWeTripartiteBO userWeTripartiteBO = byUnionIdAndOpenId.get(0);
                userWeTripartiteBO.setNickname(weChatUserInfoParam.getNickname());
                updateById(userWeTripartiteBO);
            }
        }
        return weChatUserInfoParam;
    }

    @Override
    public List<UserWeTripartiteBO> getByUnionIdAndOpenId(String unionId, String openId, String module) {
        if (StrUtil.isBlank(unionId) || StrUtil.isBlank(openId)) {
            return new ArrayList<>();
        }
        List<UserWeTripartite> list = this.lambdaQuery().eq(UserWeTripartite::getUnionId, unionId)
            .eq(UserWeTripartite::getOpenId, openId).list();
        if (CollectionUtil.isEmpty(list)){
            UserWeTripartite userWeTripartite = new UserWeTripartite();
            userWeTripartite.setOpenId(openId);
            userWeTripartite.setUnionId(unionId);
            userWeTripartite.setModule(module);
            userWeTripartite.setPid(SnowFlakeUtil.nextIdStr());
            this.save(userWeTripartite);
            ArrayList<UserWeTripartite> userWeTripartites = new ArrayList<>();
            userWeTripartites.add(userWeTripartite);
            return MapperUtil.nf().mapAsList(userWeTripartites,UserWeTripartiteBO.class);
        }
        if (CollectionUtil.isNotEmpty(list)) {
            return MapperUtil.nf().mapAsList(list, UserWeTripartiteBO.class);
        }
        return new ArrayList<>();
    }

    @Override
    public void saveOne(UserWeTripartiteBO userWeTripartiteBO) {
        if (userWeTripartiteBO == null) {
            return;
        }
        userWeTripartiteBO.setPid(SnowFlakeUtil.nextIdStr());
        UserWeTripartite map = MapperUtil.nf().map(userWeTripartiteBO, UserWeTripartite.class);
        this.save(map);
    }

    @Override
    public void updateById(UserWeTripartiteBO userWeTripartiteBO) {
        if (userWeTripartiteBO == null){
            return;
        }
        this.updateById(MapperUtil.nf().map(userWeTripartiteBO, UserWeTripartite.class));
    }

    @Override
    public List<UserWeTripartiteBO> getByTypeAndUserId(String dataByCode, String user) {
        if (StrUtil.isBlank(dataByCode)||StrUtil.isBlank(user)) {
            return null;
        }
        String dataByCode1 = ModuleEnum.getDataByCode(dataByCode);
        String s = splitPlatform(dataByCode1);
        List<UserWeTripartite> list = this.lambdaQuery().eq(UserWeTripartite::getUserId, user)
            .like(UserWeTripartite::getModule, s+"%")
            .list();
        if (CollectionUtil.isNotEmpty(list) ){
            return MapperUtil.nf().mapAsList(list,UserWeTripartiteBO.class);
        }
        return null;
    }

    @Override
    public void deleteOne(String pid){
        if (StrUtil.isNotBlank(pid)){
            this.removeById(pid);
        }
    }
    private   String splitPlatform(String module){
        if (StrUtil.isBlank(module)){
            return "" ;
        }
        if (module.contains(".")){
            String substring = module.substring(0, module.indexOf("."));
            System.out.println(substring);
            return substring;
        }
        return "";
    }

    @Override
    public List<PlatformParam> getByUserId(String userId) {
        if (StrUtil.isBlank(userId)){
            return new ArrayList<>();
        }
        List<UserWeTripartite> list = this.lambdaQuery().eq(UserWeTripartite::getUserId, userId)
            .list();
        if (CollectionUtil.isEmpty(list)){
            return new ArrayList<>();
        }
        ArrayList<PlatformParam> platformParams = new ArrayList<>();
        list.forEach(userWeTripartite -> {
            PlatformParam platformParam = new PlatformParam();
            platformParam.setPlatform(splitPlatform(userWeTripartite.getModule()));
            platformParam.setNickname(userWeTripartite.getNickname());
            platformParams.add(platformParam);

        });
        return platformParams;
    }

    @Override
    public List<String> getIdsByUserIdLikeModule(String user, String substring) {
        if (StrUtil.isBlank(user)){
            return new ArrayList<>();
        }
        List<UserWeTripartite> list = this.lambdaQuery().eq(UserWeTripartite::getUserId, user)
            .like(UserWeTripartite::getModule, substring + "%")
            .list();
      if (CollectionUtil.isEmpty(list)){
          return new ArrayList<>();
      }
         return list.stream().map(UserWeTripartite::getPid).collect(Collectors.toList());
    }

    @Override
    public void deleteBatch(List<String> idsByUserIdLikeModule) {

        if (CollectionUtil.isNotEmpty(idsByUserIdLikeModule)){
            removeByIds(idsByUserIdLikeModule);
        }
    }

    @Override
    public List<UserWeTripartiteBO> getByUnionId(String unionId) {
        if (StrUtil.isBlank(unionId)) {
            return null;
        }
        List<UserWeTripartite> list = this.lambdaQuery().eq(UserWeTripartite::getUnionId, unionId)
            .list();
        return MapperUtil.nf().mapAsList(list,UserWeTripartiteBO.class);
    }

    @Override
    public boolean ifByUserIdLikeType(String userId, String type) {
        if (StrUtil.isBlank(userId) || StrUtil.isBlank(type)){
            return true;
        }
        String dataByCode = ModuleEnum.getDataByCode(type);
        String s = splitPlatform(dataByCode);
        List<UserWeTripartite> list = this.lambdaQuery().eq(UserWeTripartite::getUserId, userId)
            .like(UserWeTripartite::getModule, s + "%")
            .list();
        if (CollectionUtil.isEmpty(list)){
            return false;
        }
        List<String> collect = list.stream().map(UserWeTripartite::getUserId).collect(Collectors.toList());
        if (!collect.contains(userId)){
            return false;
        }
        return true;
    }

    @Override
    public void unBoundByUserId(String userId) {
        if (StrUtil.isBlank(userId)){
            return;
        }
        List<UserWeTripartite> list = this.lambdaQuery().eq(UserWeTripartite::getUserId, userId).list();
        if (CollectionUtil.isNotEmpty(list)) {
            removeByIds(list.stream().map(UserWeTripartite::getPid).collect(Collectors.toList()));
        }
    }

    List<WechatRequestBO> getWechatRequest(String type) {
        List<PropertyBO> wechatAttribute = propertyService.getWechatAttribute(type);
        ArrayList<WechatRequestBO> wechatRequestBOS = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(wechatAttribute)) {
            Map<String, List<PropertyBO>> collect = wechatAttribute.stream().collect(Collectors.groupingBy(PropertyBO::getModule));

            collect.forEach((s, propertyBOS) -> {
                WechatRequestBO wechatRequestBO = new WechatRequestBO();
                propertyBOS.forEach(propertyBO -> {
                    if (propertyBO.getKey().equals("appId")) {
                        wechatRequestBO.setAppId(propertyBO.getValue());
                    }
                    if (propertyBO.getKey().equals("appSecret")) {
                        wechatRequestBO.setAppSecret(propertyBO.getValue());
                    }
                    if (propertyBO.getKey().equals("redirect_uri")) {
                        wechatRequestBO.setRedirectUri(propertyBO.getValue());
                    }
                });
                wechatRequestBOS.add(wechatRequestBO);
            });

        }
        return wechatRequestBOS;
    }
}
